#pragma once


namespace SD_Tools
{
	template <typename T> class SimpleTreeNode
	{
	private:
	public:
		DWORD Id;
		T Data;
		SimpleTreeNode<T>* Right;
		SimpleTreeNode<T>* Left;
	private:
	public:
		SimpleTreeNode(DWORD Id, const T Data): Id(Id), Data(Data), Right(NULL), Left(NULL) {};
		bool InsertNode(DWORD Id, const T Data);
		SimpleTreeNode<T>* Find(DWORD Id);
		void Delete();
	};

	template <typename T>
	bool SD_Tools::SimpleTreeNode<T>::InsertNode( DWORD Id, const T Data )
	{
		if (Id == this->Id)
		{
			return false;
		}
		else if (Id > this->Id)
		{
			if (this->Right)
			{
				return this->Right->InsertNode(Id, Data);
			}
			else
			{
				this->Right = new SimpleTreeNode(Id, Data);
				return true;
			}
		}
		else
		{
			if (this->Left)
			{
				return this->Left->InsertNode(Id, Data);
			}
			else
			{
				this->Left = new SimpleTreeNode(Id, Data);
				return true;
			}
		}
	}

	template <typename T>
	SimpleTreeNode<T>* SD_Tools::SimpleTreeNode<T>::Find( DWORD Id )
	{
		if (this->Id == Id)
		{
			return this;
		}
		else if (Id > this->Id)
		{
			if (this->Right)
			{
				return this->Right->Find(Id);
			}
			else
			{
				return NULL;
			}
		}
		else
		{
			if (this->Left)
			{
				return this->Left->Find(Id);
			}
			else
			{
				return NULL;
			}
		}
	}

	template <typename T>
	void SD_Tools::SimpleTreeNode<T>::Delete()
	{
		if (this->Right)
		{
			this->Right->Delete();
			delete this->Right;
		}
		if (this->Left)
		{
			this->Left->Delete();
			delete this->Left;
		}
	}


	//////////////////////////////////////////////////////////////////////////

	template <typename T> class SimpleTree
	{
	private:
		SimpleTreeNode<T>* Root;
		DWORD NumberOfNodes;
	public:
	private:
	public:
		SimpleTree();
		bool AddNode(DWORD Id, const T& Data);
		bool Exist(DWORD Id);
		bool GetData(DWORD Id, T* Out);
		void Clear();
		DWORD GetNodeCount();
	};

	template <typename T>
	SD_Tools::SimpleTree<T>::SimpleTree()
	{
		this->Root = NULL;
		this->NumberOfNodes = 0;
	}

	template <typename T>
	bool SD_Tools::SimpleTree<T>::AddNode( DWORD Id, const T& Data )
	{
		if (this->NumberOfNodes)
		{
			if (this->Root->InsertNode(Id, Data))
			{
				this->NumberOfNodes++;
				return true;
			}
			return false;
		}
		else
		{
			this->Root = new SimpleTreeNode<T>(Id, Data);
			this->NumberOfNodes++;
			return true;
		}
	}

	template <typename T>
	bool SD_Tools::SimpleTree<T>::Exist( DWORD Id )
	{
		if (this->NumberOfNodes)
		{
			return this->Root->Find(Id) != NULL;
		}
		return false;
	}

	template <typename T>
	bool SD_Tools::SimpleTree<T>::GetData( DWORD Id, T* Out )
	{
		SimpleTreeNode<T>* TempNodePtr;
		if (this->NumberOfNodes)
		{
			TempNodePtr = this->Root->Find(Id);
			if (TempNodePtr)
			{
				*Out = TempNodePtr->Data;
				return true;
			}
		}
		return false;
	}

	template <typename T>
	void SD_Tools::SimpleTree<T>::Clear()
	{
		this->Root->Delete();
		delete this->Root;
		this->Root = NULL;
		this->NumberOfNodes = 0;
	}

	template <typename T>
	DWORD SD_Tools::SimpleTree<T>::GetNodeCount()
	{
		return this->NumberOfNodes;
	}

}












